#include "graphcontrolwidget.h"
#include <QVBoxLayout>

#include <QtVariantEditorFactory>
#include <QtVariantPropertyManager>
#include <QtVariantProperty>
#include <QtProperty>

GraphControlWidget::GraphControlWidget(QWidget *parent)
	: QDockWidget(parent)
{
	m_manager = new QtVariantPropertyManager(this);
	m_factory = new QtVariantEditorFactory(this);
	setWindowTitle(trUtf8("Graph control panel"));
	m_graphScene = 0;
	m_menuBar = new QMenuBar(this);
	m_menuBar->setMinimumHeight(21);
	m_browser = new QtTreePropertyBrowser(this);
	m_graphMenu = new QMenu(trUtf8("Graph"), this);
	m_graphAction = new QAction(trUtf8("Create graph"), this);
	m_vertexAction = new QAction(trUtf8("Add vertex"), this);
	m_vertexAction->setEnabled(false);
	m_edgeAction = new QAction(trUtf8("Add edge"), this);
	m_edgeAction->setEnabled(false);
	m_drawAction = new QAction(trUtf8("Draw graph"), this);
	m_drawAction->setEnabled(false);
	m_colorEdges = new QAction(trUtf8("Color some edges"), this);
	m_colorEdges->setEnabled(false);
	m_graphMenu->addAction(m_graphAction);
	m_graphMenu->addSeparator();
	m_graphMenu->addAction(m_vertexAction);
	m_graphMenu->addAction(m_edgeAction);
	m_graphMenu->addSeparator();
	m_graphMenu->addAction(m_drawAction);
	m_graphMenu->addAction(m_colorEdges);
	m_menuBar->addMenu(m_graphMenu);
	QVBoxLayout *lo = new QVBoxLayout;
	lo->setMargin(2);
	lo->setSpacing(2);
	QWidget *w = new QWidget(this);
	w->setLayout(lo);
	lo->addWidget(m_menuBar);
	lo->addWidget(m_browser);

	setWidget(w);
	setContentsMargins(0, 0, 0, 0);

	connect(m_drawAction, SIGNAL(triggered()), this, SLOT(drawGraphClicked()));
	connect(m_graphAction, SIGNAL(triggered()), this, SLOT(createGraph()));
	connect(m_colorEdges, SIGNAL(triggered()), this, SLOT(colorSomeEdges()));

	connect(m_manager, SIGNAL(valueChanged(QtProperty*,QVariant)), this, SLOT(propertyValueChanged(QtProperty*,QVariant)));
}

void GraphControlWidget::drawGraphClicked()
{
	if (m_graph) {
		m_graphScene = new GraphGui(*m_graph, this);
		emit newGraph(m_graphScene);
		m_drawAction->setEnabled(false);
		m_colorEdges->setEnabled(true);
	}
}

void GraphControlWidget::createGraph()
{
	m_graph = new Graph;

	/*
	m_graph->addEdge("A", "B", 158);
	m_graph->addEdge("A", "C", 12);
	m_graph->addEdge("A", "D", 32);
	m_graph->addEdge("B", "C", 34);
	m_graph->addEdge("B", "E", 763);
	m_graph->addEdge("C", "D", 123);
	m_graph->addEdge("C", "E", 234);
	m_graph->addEdge("C", "F", 345);
	m_graph->addEdge("D", "E", 456);
	m_graph->addEdge("D", "F", 432);
	m_graph->addEdge("D", "G", 567);
	m_graph->addEdge("A", "E", 321); */

	m_graph->createGraph(15, 3);

	m_vertexAction->setEnabled(true);
	m_edgeAction->setEnabled(true);
	m_drawAction->setEnabled(true);

	prepareBrowser();
}

void GraphControlWidget::colorSomeEdges()
{
	if (!m_graph)
		return;

	/*
	QList<Edge> edges = m_graph->edges();

	int count = qrand()%edges.size();
	QList<Edge> toColor;
	for (int i = 0; i < count; ++i) {
		Edge e = edges.at(qrand()%edges.size());
		if (!toColor.contains(e))
			toColor.append(e);
	}*/

	m_graph->preciseSalesman();

	QList<Vertex> vl = m_graph->route();

	//qdebug() << vl.size();

	QList<Edge> toColor;

	for(int i = 1; i < vl.size(); ++i)
	{
		QList<Edge> el = m_graph->edges(vl.at(i - 1));

		foreach(Edge e, el)
		{
			if(e.v() == vl.at(i) || e.u() == vl.at(i))
			{
				toColor.append(e);
			}
		}

		//toColor.append(Edge(vl.at(i - 1), vl.at(i)));
	}
	m_graphScene->colorEdges(toColor, Qt::green);
}

void GraphControlWidget::prepareBrowser()
{
	QtProperty *graphItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), trUtf8("Graph"));
	QList<Vertex> vertices = m_graph->vertices();
	QtProperty *verticesItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), trUtf8("Vertices"));
	graphItem->addSubProperty(verticesItem);
	foreach (Vertex v, vertices) {
		QtVariantProperty *prop = m_manager->addProperty(QVariant::String, trUtf8("Vertex"));
		GraphVertexPropertyItem *item = new GraphVertexPropertyItem;
		item->vertex = v;
		m_propToItem.insert(prop, item);
		prop->setValue(v.name());
		verticesItem->addSubProperty(prop);
	}
	QList<Edge> edges = m_graph->edges();
	QtProperty *edgesItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), trUtf8("Edges"));
	graphItem->addSubProperty(edgesItem);
	foreach (Edge e, edges) {
		QtProperty *edgeItem = m_manager->addProperty(QtVariantPropertyManager::groupTypeId(), trUtf8("Edges"));
		// u
		QtVariantProperty *propu = m_manager->addProperty(QVariant::String, trUtf8("Vertex U"));
		GraphEdgeUPropertyItem *itemu = new GraphEdgeUPropertyItem;
		itemu->edge = e;
		m_propToItem.insert(propu, itemu);
		propu->setValue(e.u().name());
		edgeItem->addSubProperty(propu);
		// v
		QtVariantProperty *propv = m_manager->addProperty(QVariant::String, trUtf8("Vertex V"));
		GraphEdgeVPropertyItem *itemv = new GraphEdgeVPropertyItem;
		itemv->edge = e;
		m_propToItem.insert(propv, itemv);
		propv->setValue(e.v().name());
		edgeItem->addSubProperty(propv);
		// length
		QtVariantProperty *propl = m_manager->addProperty(QVariant::Int, trUtf8("Length"));
		GraphEdgeLengthPropertyItem *iteml = new GraphEdgeLengthPropertyItem;
		iteml->edge = e;
		m_propToItem.insert(propl, iteml);
		propl->setValue(e.length());
		edgeItem->addSubProperty(propl);
		edgesItem->addSubProperty(edgeItem);
	}

	m_browser->setFactoryForManager(m_manager, m_factory);
	m_browser->addProperty(graphItem);
}

void GraphControlWidget::addEdge()
{
}

void GraphControlWidget::addVertex()
{
}

void GraphControlWidget::propertyValueChanged(QtProperty *prop, const QVariant &value)
{
}
